package com.mh.controller;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.mh.config.OssConfig;
import com.mh.dto.OssPolicyDTO;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * Date:2025/5/8
 * author:zmh
 * description: 生成Post Object所需的签名参数
 **/

@CrossOrigin
@RestController
@RequestMapping("/oss")
@Slf4j
public class OssController {

    @Autowired
    private OSS ossClient;

    @Autowired
    private OssConfig ossConfig;

    @GetMapping("/getOssPolicy")
    public OssPolicyDTO getPostObjectSignature(){
        // 初始化DTO对象，后续用来封装返回的数据
        OssPolicyDTO dto = new OssPolicyDTO();

        try {
            // 获取并初始化过期时间
            long expireEndTime = System.currentTimeMillis() + ossConfig.getExpireTime() * 1000;
            Date expiration = new Date(expireEndTime);

            // 创建并新增上传策略：过期时间，上传的目录前缀
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ossConfig.getDir());

            // 获取策略字符串 -> 编码utf字节数组
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            //再转为字符串
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);

            // 执行签名
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            // 构建返回参数
            dto.setOssAccessKeyId(ossConfig.getAccessKeyId());
            dto.setPolicy(encodedPolicy);
            dto.setSignature(postSignature);
            dto.setDir(ossConfig.getDir());
            dto.setHost(ossConfig.getHost());
        } catch (
                OSSException oe) {
            System.out.println("捕获到一个OSS异常，这意味着您的请求已到达OSS，"
                    + "但由于某种原因被拒绝并返回了错误响应。");
            // 假设此方法存在
            System.out.println("HTTP状态码: " + oe.getRawResponseError());
            System.out.println("错误信息: " + oe.getErrorMessage());
            System.out.println("错误代码: " + oe.getErrorCode());
            System.out.println("请求ID: " + oe.getRequestId());
            System.out.println("主机ID: " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("捕获到一个客户端异常，这意味着客户端在尝试与OSS通信时"
                    + "遇到了严重的内部问题，例如无法访问网络。");
            System.out.println("错误信息: " + ce.getMessage());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        // 返回DTO对象数据
        return dto;
    }

}
